home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / Xconq 7.1.0 / src / xconq-7.1.0 / kernel / unix.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-07  |  5.4 KB  |  291 lines  |  [TEXT/R*ch]

  1. /* Unix-specific code for Xconq.
  2.    Copyright (C) 1987, 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1996
  3.    Stanley T. Shebs.
  4.  
  5. Xconq is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2, or (at your option)
  8. any later version.  See the file COPYING.  */
  9.  
  10. /* Unix interface stuff.  Do NOT attempt to use this file in a non-Unix
  11.    system, not even an ANSI one! */
  12.  
  13. #include "config.h"
  14. #include "misc.h"
  15. #include "dir.h"
  16. #include "lisp.h"
  17. #include "module.h"
  18. #include "system.h"
  19.  
  20. extern void close_displays PARAMS ((void));
  21.  
  22. #include <signal.h>
  23. #include <unistd.h>
  24. #include <sys/time.h>
  25.  
  26. #ifndef XCONQLIB
  27. #define XCONQLIB "../lib"
  28. #endif
  29.  
  30. char *
  31. default_library_filename()
  32. {
  33.     return XCONQLIB;
  34. }
  35.  
  36. char *
  37. news_filename()
  38. {
  39.     /* (should search in library list) */
  40.     make_pathname(xconq_libs->path, NEWSFILE, "", spbuf);
  41.     return spbuf;
  42. }
  43.  
  44. char *
  45. saved_game_filename()
  46. {
  47.     return "save.xconq";
  48. }
  49.  
  50. char *
  51. checkpoint_filename()
  52. {
  53.     return "check.xconq";
  54. }
  55.  
  56. char *
  57. error_save_filename()
  58. {
  59.     return "ack!.xconq";
  60. }
  61.  
  62. char *
  63. statistics_filename()
  64. {
  65.     return STATSFILE;
  66. }
  67.  
  68. /* Attempt to open a library file. */
  69.  
  70. FILE *
  71. open_module_library_file(module)
  72. Module *module;
  73. {
  74.     LibraryPath *p;
  75.     FILE *fp;
  76.  
  77.     /* Don't try to do on anon modules? */
  78.     if (module->name == NULL)
  79.       return NULL;
  80.     for_all_library_paths(p) {
  81.     /* Generate library pathname. */
  82.     make_pathname(p->path, module->name, "g", spbuf);
  83.     /* Now try to open the file. */
  84.     fp = fopen(spbuf, "r");
  85.     if (fp != NULL) {
  86.         /* Remember the filename where we found it. */
  87.         module->filename = copy_string(spbuf);
  88.         return fp;
  89.     }
  90.     }
  91.     return NULL;
  92. }
  93.  
  94. FILE *
  95. open_module_explicit_file(module)
  96. Module *module;
  97. {
  98.     if (module->filename == NULL)
  99.       return NULL;
  100.     return (fopen(module->filename, "r"));
  101. }
  102.  
  103. FILE *
  104. open_library_file(filename)
  105. char *filename;
  106. {
  107.     char fullnamebuf[1024];
  108.     LibraryPath *p;
  109.     FILE *fp = NULL;
  110.  
  111.     fp = fopen(filename, "r");
  112.     if (fp != NULL) {
  113.     return fp;
  114.     }
  115.     for_all_library_paths(p) {
  116.     /* Generate library pathname. */
  117.     make_pathname(p->path, filename, NULL, fullnamebuf);
  118.     fp = fopen(fullnamebuf, "r");
  119.     if (fp != NULL) {
  120.         return fp;
  121.     }
  122.     }
  123.     return NULL;
  124. }
  125.  
  126. FILE *
  127. open_scorefile_for_reading(name)
  128. char *name;
  129. {
  130.     FILE *fp;
  131.     
  132.     fp = fopen(name, "r");
  133.     return fp;
  134. }
  135.  
  136. FILE *
  137. open_scorefile_for_writing(name)
  138. char *name;
  139. {
  140.     FILE *fp;
  141.     
  142.     fp = fopen(name, "a");
  143.     return fp;
  144. }
  145.  
  146. void
  147. make_pathname(path, name, extn, pathbuf)
  148. char *path, *name, *extn, *pathbuf;
  149. {
  150.     strcpy(pathbuf, "");
  151.     if (!empty_string(path)) {
  152.     strcat(pathbuf, path);
  153.     strcat(pathbuf, "/");
  154.     }
  155.     strcat(pathbuf, name);
  156.     /* Don't add a second identical extension, but do add if extension
  157.        is different (in case we want "foo.12" -> "foo.12.g" for instance) */
  158.     if (strrchr(name, '.')
  159.     && extn
  160.     && strcmp((char *) strrchr(name, '.') + 1, extn) == 0)
  161.       return;
  162.     if (!empty_string(extn)) {
  163.     strcat(pathbuf, ".");
  164.     strcat(pathbuf, extn);
  165.     }
  166. }
  167.  
  168. /* Remove a saved game from the system. */
  169.  
  170. void
  171. remove_saved_game()
  172. {
  173.     unlink(saved_game_filename());
  174. }
  175.  
  176. /* Default behavior on explicit kill. */
  177.  
  178. void
  179. stop_handler(sig, code, scp, addr)
  180. int sig, code;
  181. struct sigcontext *scp;
  182. char *addr;     
  183. {
  184.     close_displays();
  185.     exit(1);
  186. }
  187.  
  188. /* This routine attempts to save the state before dying. */
  189.  
  190. void
  191. crash_handler(sig, code, scp, addr)
  192. int sig, code;
  193. struct sigcontext *scp;
  194. char *addr;     
  195. {
  196.     static int already_been_here = FALSE;
  197.  
  198.     if (!already_been_here) {
  199.     already_been_here = TRUE;
  200.     close_displays();  
  201.     printf("Fatal error encountered. Signal %d code %d\n", sig, code);
  202.     write_entire_game_state("ack!.xconq");
  203.     }
  204.     abort();
  205. }
  206.  
  207. /* Accidental disconnection saves state. */
  208.  
  209. void
  210. hup_handler(sig, code, scp, addr)
  211. int sig, code;
  212. struct sigcontext *scp;
  213. char *addr;     
  214. {
  215.     static int already_been_here = FALSE;
  216.  
  217.     if (!already_been_here) {
  218.     already_been_here = TRUE;
  219.     close_displays();
  220.     printf("Somebody was disconnected, saving the game.\n");
  221.     write_entire_game_state("ack!.xconq");
  222.     }
  223.     abort();
  224. }
  225.  
  226. void
  227. init_signal_handlers()
  228. {
  229.     signal(SIGINT, stop_handler);
  230.     if (0 /* don't accidently quit */ && !Debug) {
  231.     signal(SIGINT, SIG_IGN);
  232.     } else {
  233.     signal(SIGINT, SIG_DFL);
  234. /*    signal(SIGINT, crash_handler);  */
  235.     }
  236.     signal(SIGHUP, hup_handler);
  237.     signal(SIGSEGV, crash_handler);
  238.     signal(SIGFPE, crash_handler);
  239.     signal(SIGILL, crash_handler);
  240.     signal(SIGINT, crash_handler);
  241.     signal(SIGQUIT, crash_handler);
  242.     signal(SIGTERM, crash_handler);
  243.     /* The following signals may not be available everywhere. */
  244. #ifdef SIGBUS
  245.     signal(SIGBUS, crash_handler);
  246. #endif /* SIGBUS */
  247. #ifdef SIGSYS
  248.     signal(SIGSYS, crash_handler);
  249. #endif /* SIGSYS */
  250. }
  251.  
  252. struct timeval reallasttime = { 0, 0 };
  253.  
  254. struct timeval realcurtime;
  255.  
  256. int
  257. n_seconds_elapsed(n)
  258. int n;
  259. {
  260.     gettimeofday(&realcurtime, NULL);
  261.     if (realcurtime.tv_sec > (reallasttime.tv_sec + (n - 1))) {
  262.     reallasttime = realcurtime;
  263.     return TRUE;
  264.     } else {
  265.     return FALSE;
  266.     }
  267. }
  268.  
  269. struct timeval reallastmstime = { 0, 0 };
  270.  
  271. int
  272. n_ms_elapsed(n)
  273. int n;
  274. {
  275.     int interval;
  276.     struct timeval tmprealtime;
  277.  
  278.     gettimeofday(&tmprealtime, NULL);
  279.     interval =
  280.       (tmprealtime.tv_sec - reallastmstime.tv_sec) * 1000
  281.     + (tmprealtime.tv_usec - reallastmstime.tv_usec) / 1000;
  282.     return (interval > n);
  283. }
  284.  
  285. void
  286. record_ms()
  287. {
  288.     gettimeofday(&reallastmstime, NULL);
  289. }
  290.  
  291.